/**
 * 
 */
package hu.gbalage.owlforms.xforms.gen;

import java.net.URI;
import java.util.Set;

import org.semanticweb.owl.inference.OWLReasonerException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import hu.gbalage.owlforms.api.Field;
import hu.gbalage.owlforms.api.Form;
import hu.gbalage.owlforms.api.data.FieldData;
import hu.gbalage.owlforms.api.data.FormData;
import hu.gbalage.owlforms.xforms.work.Boot;

/**
 * @author balage
 *
 */
public class FormDataParser {

	public static FormData parse(Document result){
		return parse(result.getDocumentElement());
	}
	
	private static Field findField(Form in, URI what){
		for(Field f : in.listFields())
			if (f.getURI().equals(what))
				return f;
		return null;
	}
	
	private static void insertValues(Element values, FieldData into){
		NodeList vs = values.getChildNodes();
		for(int i=0;i<vs.getLength();i++){
			Element value = (Element)vs.item(i);
			if (into.getField().isPrimitive()){
				Set<URI> types = into.getField().getAcceptedTypes();
				URI type = types.isEmpty() ? URI.create("http://www.w3.org/2001/XMLSchema#string") :types.iterator().next();
				into.insertValue(type).asPrimitiveValue().setValue(value.getTextContent());
			}else{
				if (into.getField().asComplexField().isImported()){
					//TODO: polymorph inputs..? not an easy one..
					try {
						URI  inputuri = URI.create(value.getTextContent());
						into.insertCompositeValue(Boot.load(into.getField().asComplexField().getContainedForm()[0], inputuri.getFragment()));
					} catch (OWLReasonerException e) {
						e.printStackTrace();
					}
				}else{
					// support for polymorphism
					int selected = 0;
					NodeList list = value.getChildNodes();
					for(int j=0;j<list.getLength();j++){
						if (list.item(j) instanceof Element){
							Element v = (Element)list.item(j);
							if (v.getAttribute("selected").equals("true")) selected = j;
						}
					}
					System.out.println("Polymorph data: "+selected+"/"+value.getChildNodes().getLength());
					FormData inserted = parse((Element)value.getChildNodes().item(selected));
					into.insertCompositeValue(inserted);
				}
			}
		}
	}
	
	public static FormData parse(Element result){
		//Load form
		URI uri = URI.create(result.getAttribute("uri"));
		Form form = Boot.manager.getFactory().createForm(uri);
		
		//create empty form data
		String random = Math.round(Math.random()*10000000)+"";
		FormData data = Boot.manager.getFormsDataFactory().createEmptyData(form, URI.create("http://owlforms.gbalage.hu/usr/saved#"+uri.getFragment()+"_"+random));
		
		//fill data with values
		NodeList fields = result.getChildNodes();
		for(int i=0;i<fields.getLength();i++){
			Element field = (Element)fields.item(i);
			FieldData fdata = data.getData(findField(form, URI.create(field.getAttribute("uri"))));
			insertValues(field,fdata);
		}
		
		return data;
	}
	
}
